Legacy of the Elder Star
Kickbomb Entertainment | Founder | March 2013 - June 2016
Legacy of the Elder Star is a side-scrolling shoot-em-up with a twist: using a one-handed, mouse-driven control scheme, you'll dodge and strike with 1:1 precision and unlimited movement speed. Evade intense bullet patterns in the blink of an eye, then dash through entire enemy squads to crush them in a single gesture. Movement is everything in Legacy of the Elder Star, and no other shoot 'em up moves like this.
Development overview
This was my first major indie title built for commercial release. It was entirely self-funded, self-directed, and self-published. I did all the design, programming, music, and UI, and worked with local artist Erik Exeter to produce the art style, game assets, and animations.
The game is built in Unity and shipped on Unity 5.4. I used 2D Toolkit for in-game sprites and UI, and Spine for character and environment animations. Steamworks.NET provided Steam API support with which I integrated leaderboards and achievements. I also wrote extensive custom utilities and editor extensions for object pooling, visual level scripting, sequencing effects, and mixing audio, among other things.
Throughout development I produced several trailers which I scripted, shot, edited, and scored, including the launch trailer shown above.
Soundtrack
For this game, I wrote a driving melodic electro-rock soundtrack, evoking and modernizing the chiptune style of old-school arcade shoot 'em ups. I put a lot of emphasis here on developing, reprising, and interweaving musical themes.
🏆 "I have to start with praise for the music of Elder Star. Props to the composer for writing something that's at once epic, spacey and robotic that evokes the classic 8/16-bit legends."
— Steam review by PapaBrain
- Legacy of the Elder Star
- The Perimeter
- The Infinite Legion
- The Garden
- The Fragments
- The Spires
- The Fleet
- Finale
- The Elder Star
Accolades
🏆 "Legacy of the Elder Star knocks it out of the park, retaining the retro charm of the genre without shackling itself to the past."
— GamerPros.co
🏆 "[The dash is] a great mechanic, that allows for a fresh new take on an age old genre and makes for an intense and thoroughly enjoyable shmup experience."
— Alpha Beta Gamer
🏆 "The game runs like heaven, and controls wonderfully."
— Enemy Slime
🏆 "Fans of the genre should definitely be checking this game out."
— True PC Gaming
🏆 "Has an incredibly holistic design that completely understands how shmups can benefit from being designed centrally for the PC instead of being mere ports of arcade games... In both design and execution, the game has very few peers."
— Steam review by Owen Ketillson
🏆 "Fascinating, 1:1 mouse control is something we don't see often in shmups, but there may be something we're missing there since it feels super fluid and accessible in this game."
— Steam review by Structor
🏆 "Simple. Pleasant. Hard. Loveable."
— Steam review by HappyLarry
🏆 "This game has accessibility options out the ass. Colorblind? There's a toggle. Autism? Toggles for slowing it down (or speed it up) and reducing flashes / shakes. One handed? You can play with just a mouse. On top of all that it's free so if you're poor you can afford it. Great for kids too because if you die you can just hit continue (no permadeath as far as I could see.)"
— Steam review by Scary Guy
Press coverage
- GamerPros – Legacy of the Elder Star Review
- Enemy Slime – Review: Legacy of the Elder Star
- TechRaptor – To The Green: Legacy of the Elder Star
- Gamers Haven – The Quickest of Looks at Legacy of the Elder Star
- True PC Gaming – Legacy of the Elder Star Demo Review
- Fast-Paced Reviews – Legacy of the Elder Star: Brush Them Up!
- Alpha Beta Gamer – Tumblr
- DigiSpun – Legacy of the Elder Star Arcade Shooter Looks Amazing
How to get it
Legacy of the Elder Star can be downloaded for free from itch.io and Steam.
Development techniques
Here are some noteworthy techniques and implementation details that went into this project.
Object pooling
Shoot-em-ups spawn enemies and bullets (especially bullets) at a terrifying rate. Unity's default Instantiate()
call is pretty heavy and becomes a CPU performance bottleneck for this use case, so I wrote an object pooling system to take care of it.
The Recycler
class provides public API replacements for Instantiate
and Destroy
which manage pooling automatically and transparently. The Recycler maintains a dictionary of object pools: the key is a prefab, and the value is a list of disabled instances of that prefab. When I instantiate a prefab, the Recycler pops one of these instances, enables it, and returns it as the newly "instantiated" instance. If the pool is empty, a new instance is created on-the-fly in the normal "heavyweight" way.
Since those on-the-fly allocations are heavy, the Recycler also provides a Preallocate
call which allows me to pre-fill the pool with a specified number of instances of each prefab type. I do this under the guise of a load screen. The Recycler's custom inspector provides runtime pool counts in an easily-readable format; I used that to estimate good initial pool counts for preallocation. (The on-the-fly allocation is really just a safeguard; in practice it's almost never hit.)
When an object is destroyed via the Recycler API, it's simply disabled and popped back onto its pool.
With appropriate preallocation -- which is time-sliced so the load screen can continue to animate during this process, despite object instantiations being required to run on the main thread -- the Recycler is capable of spawning upwards of 10,000 bullets per second with minimal performance impact. In practice, the game never gets quite that hectic, so there's plenty of performance headroom to work with.
Level scripting
I created a graphical editor for visually laying out the sequence of events in each level. This allowed for easy rapid iteration on level progressions.
With this tool I could quickly place different event types -- play music, show HUD messages, enemy spawn sequences, boss encounters, etc. -- and adjust their timing. The level could start at any event, so testing later portions of the level was as easy as double-clicking the event of interest to mark it as the new (temporary) starting point, and hitting Play.
Events could also execute in parallel by disabling the Block?
settings. This was useful for things like triggering a HUD message with a slightly-delayed, but overlapping, boss arrival. I didn't use this often, but it came in really handy for those cases where it was needed.
The core campaign levels had linear event sequences, but the daily challenges used a randomized non-linear sequence, which the tool also supported:
In this case, any event with multiple outgoing connections would choose one of those connections at random each time it finished executing. Combining that with a looping setup provided randomly-generated event sequences at virtually no cost. The daily challenges simply injected a random seed -- based on the current date -- when the level sequence initialized, ensuring the same sequence was generated for every run that day.
Custom audio mixer
I started work on Legacy of the Elder Star during the 3.x release cycle, long before Unity added their native Audio Mixer, which meant the only audio implementation available to me out of the box was adding AudioSource components to everything. That's fine as it goes, but it makes mixing a pain because the mix controls for your sounds are scattered all over your project, buried in scenes and prefabs. I wanted a cleaner way to work with audio, so I wrote a simple custom audio mixer.
💡 You'll see a
Mixer Group
property in the screenshot; that was added after upgrading to the 5.x release cycle to integrate with the native Audio Mixer, where I combined groups of sound events into buses like "Weapons", "Explosions", and "Interface", further simplifying mixing.
This worked a bit like a stripped-down version of FMOD: I would create named sound events, and invoke them in code using that name instead of an asset reference. The sound event took care of random clip variation, simultaneous voice limiting, and ducking. Each sound event had its own volume slider, all accessible right from the AudioMixer
custom inspector UI, which made final mixdown a breeze. Because there were many sound events, I didn't list them in a big array, but instead created the Sound Event
dropdown you can see in the screenshot, from which you could pick which sound event to edit, with the rest of the UI showing editing controls for just that sound event.
Lessons learned
This was my first completely independent commercial release, which meant I had to learn how to start and run a business: Kickbomb Entertainment. After a decade working for other people's studios, it was extremely enlightening -- and at times challenging -- to see the view from the other side of the table. That business lasted four years, and while it's now shuttered, it remains one of the proudest achievements of my professional life.
As it turns out, marketing is hard, and is a completely different skill set from development. I underestimated both the importance and difficulty of that aspect of the product development pipeline. I made mistakes and tried new things, and while ultimately the game's market penetration still fell short of expectations, I came out the other side with a much clearer and more practical understanding of the state of the industry and how rapidly things have been changing.